var dataimport_timeout = 2000;
var cookie_dataimport_autorefresh = 'dataimport_autorefresh';

sammy.bind('dataimport_queryhandler_load', function(event, params) {
	var core_basepath = params.active_core.attr('data-basepath');

	$.ajax({
		url : core_basepath + '/admin/mbeans?cat=QUERYHANDLER&wt=json',
		dataType : 'json',
		beforeSend : function(xhr, settings) {},
		success : function(response, text_status, xhr) {
			var handlers = response['solr-mbeans'][1];
			var dataimport_handlers = [];
			for ( var key in handlers) {
				if (handlers[key]['class'] !== key && handlers[key]['class'] === 'org.apache.solr.handler.dataimport.DataImportHandler') {
					dataimport_handlers.push(key);
				}
			}
			params.callback(dataimport_handlers);
		},
		error : function(xhr, text_status, error_thrown) {},
		complete : function(xhr, text_status) {}
	});
});

// #/:core/dataimport
sammy.get(new RegExp(app.core_regex_base + '\\/(dataimport)$'), function(context) {
	sammy.trigger('dataimport_queryhandler_load', {
		active_core : this.active_core,
		callback : function(dataimport_handlers) {
			if (0 === dataimport_handlers.length) {
				$('#content').html('sorry, no dataimport-handler defined!');

				return false;
			}

			context.redirect(context.path + '/' + dataimport_handlers[0]);
		}
	});
});

// #/:core/dataimport
sammy.get(new RegExp(app.core_regex_base + '\\/(dataimport)\\/'), function(context) {
	var core_basepath = this.active_core.attr('data-basepath');
	var content_element = $('#content');

	var path_parts = this.path.match(/^(.+\/dataimport\/)(.*)$/);
	var handler_url = core_basepath + path_parts[2];

	$('li.dataimport', this.active_core).addClass('active');

	$.get('tpl/dataimport.html', function(template) {
		content_element.html(template);

		var dataimport_element = $('#dataimport', content_element);
		var form_element = $('#form', dataimport_element);
		var config_element = $('#config', dataimport_element);
		var error_element = $('#error', dataimport_element);
		var debug_response_element = $('#debug_response', dataimport_element);

		var autorefresh_status = false;
		var debug_mode = false;

		// handler

		sammy.trigger('dataimport_queryhandler_load', {
			active_core : context.active_core,
			callback : function(dataimport_handlers) {
				var handlers_element = $('#navigation ul', form_element);
				var handlers = [];

				for (var i = 0; i < dataimport_handlers.length; i++) {
					handlers.push('<li><a href="' + path_parts[1] + dataimport_handlers[i] + '">' + dataimport_handlers[i] + '</a></li>');
				}

				$(handlers_element).html(handlers.join("\n"));

				$('a[href="' + context.path + '"]', handlers_element).closest('li').addClass('current');

				$('form', form_element).show();
			}
		});

		// config

		function dataimport_fetch_config() {
			$.ajax({
				url : handler_url + '?command=show-config&indent=true',
				dataType : 'xml',
				context : $('#dataimport_config', config_element),
				beforeSend : function(xhr, settings) {
					error_element.empty().hide();
				},
				success : function(config, text_status, xhr) {
					dataimport_element.removeClass('error');

					config_element.addClass('hidden');

					var entities = [ '<option value=""></option>' ];

					$('document > entity', config).each(function(i, element) {
						entities.push('<option>' + $(element).attr('name').esc() + '</option>');
					});

					$('#entity', form_element).html(entities.join("\n"));

					$('.editable textarea', this).val(xhr.responseText.replace(/\n+$/, ''));
				},
				error : function(xhr, text_status, error_thrown) {
					if ('parsererror' === error_thrown) {
						dataimport_element.addClass('error');

						error_element.text('Dataimport XML-Configuration is not valid').show();

						config_element.removeClass('hidden');
					}
				},
				complete : function(xhr, text_status) {
					var code = $('<pre class="syntax language-xml"><code>' + xhr.responseText.esc() + '</code></pre>');
					$('.formatted', this).html(code);

					if ('success' === text_status) {
						hljs.highlightBlock(code.get(0));
					}
				}
			});
		}
		dataimport_fetch_config();

		$('.block .toggle', dataimport_element).die('click').live('click', function(event) {
			$(this).parents('.block').toggleClass('hidden');

			return false;
		})

		var reload_config_element = $('.reload_config', config_element);
		reload_config_element.die('click').live('click', function(event) {
			$.ajax({
				url : handler_url + '?command=reload-config',
				dataType : 'xml',
				context : $(this),
				beforeSend : function(xhr, settings) {
					this.removeClass('error').addClass('loader');
				},
				success : function(response, text_status, xhr) {
					this.addClass('success');

					window.setTimeout(function() {
						reload_config_element.removeClass('success');
					}, 5000);
				},
				error : function(xhr, text_status, error_thrown) {
					this.addClass('error');
				},
				complete : function(xhr, text_status) {
					this.removeClass('loader');

					dataimport_fetch_config();
				}
			});
			return false;
		});

		var debug_mode_element = $('.debug_mode', config_element);
		debug_mode_element.die('click').live('click', function(event) {
			var self = $(this);
			var block = self.closest('.block')

			var debug_checkbox = $('input[name="debug"]', form_element);
			var submit_span = $('button[type="submit"] span', form_element);

			debug_mode = !debug_mode;

			block.toggleClass('debug_mode', debug_mode);

			if (debug_mode) {
				block.removeClass('hidden');

				debug_checkbox.attr('checked', 'checked').trigger('change');

				submit_span.data('original', submit_span.text()).text(submit_span.data('debugmode'));
			} else {
				submit_span.text(submit_span.data('original')).removeData('original');
			}
		});

		// abort

		var abort_import_element = $('.abort-import', dataimport_element);
		abort_import_element.off('click').on('click', function(event) {
			var span_element = $('span', this);

			$.ajax({
				url : handler_url + '?command=abort&wt=json',
				dataType : 'json',
				type : 'GET',
				context : $(this),
				beforeSend : function(xhr, settings) {
					span_element.addClass('loader');
				},
				success : function(response, text_status, xhr) {
					span_element.data('original', span_element.text()).text(span_element.data('aborting'));

					this.removeClass('warn').addClass('success');

					window.setTimeout(function() {
						$('span', abort_import_element).removeClass('loader').text(span_element.data('original')).removeData('original');

						abort_import_element.removeClass('success').addClass('warn');
					}, dataimport_timeout * 2);

					dataimport_fetch_status();
				}
			});
			return false;
		});

		// state

		var status_button = $('form button.refresh-status', form_element);

		status_button.off('click').on('click', function(event) {
			dataimport_fetch_status();
			return false;
		}).trigger('click');

		function dataimport_fetch_status(clear_timeout) {
			if (clear_timeout) {
				app.clear_timeout();
			}

			$.ajax({
				url : handler_url + '?command=status&indent=true&wt=json',
				dataType : 'json',
				beforeSend : function(xhr, settings) {
					$('span', status_button).addClass('loader');
				},
				success : function(response, text_status, xhr) {
					var state_element = $('#current_state', content_element);

					var status = response.status;
					var rollback_time = response.statusMessages.Rolledback || null;
					var abort_time = response.statusMessages.Aborted || null;

					var messages = response.statusMessages;
					var messages_count = 0;
					for ( var key in messages) {
						messages_count++;
					}

					function dataimport_compute_details(response, details_element, elapsed_seconds) {
						details_element.show();

						// --

						var document_config = {
							'Requests' : 'Total Requests made to DataSource',
							'Fetched' : 'Total Rows Fetched',
							'Skipped' : 'Total Documents Skipped',
							'Processed' : 'Total Documents Processed'
						};

						var document_details = [];
						for ( var key in document_config) {
							var value = parseInt(response.statusMessages[document_config[key]], 10);

							var detail = '<abbr title="' + document_config[key].esc() + '">' + key.esc() + '</abbr>: ' + app.format_number(value).esc();
							if (elapsed_seconds && 'skipped' !== key.toLowerCase()) {
								detail += ' <span>(' + app.format_number(Math.round(value / elapsed_seconds)).esc() + '/s)</span>'
							}

							document_details.push(detail);
						}
						;

						$('.docs', details_element).html(document_details.join(', '));

						// --

						var dates_config = {
							'Started' : 'Full Dump Started',
							'Aborted' : 'Aborted',
							'Rolledback' : 'Rolledback'
						};

						var dates_details = [];
						for ( var key in dates_config) {
							var value = response.statusMessages[dates_config[key]];

							if (value) {
								var detail = '<abbr title="' + dates_config[key].esc() + '">' + key.esc() + '</abbr>: ' + '<abbr class="time">' + value.esc() + '</abbr>';
								dates_details.push(detail);
							}
						}
						;

						var dates_element = $('.dates', details_element);

						dates_element.html(dates_details.join(', '));

						$('.time', dates_element).removeData('timeago').timeago();
					}
					;

					var get_time_taken = function get_default_time_taken() {
						var time_taken_text = response.statusMessages['Time taken'];
						return app.convert_duration_to_seconds(time_taken_text);
					};

					var get_default_info_text = function default_info_text() {
						var info_text = response.statusMessages[''] || '';

						// format numbers included in status nicely
						info_text = info_text.replace(/\d{4,}/g, function(match, position, string) {
							return app.format_number(parseInt(match, 10));
						});

						var time_taken_text = app.convert_seconds_to_readable_time(get_time_taken());
						if (time_taken_text) {
							info_text += ' (Duration: ' + time_taken_text.esc() + ')';
						}

						return info_text;
					};

					var show_info = function show_info(info_text, elapsed_seconds) {
						$('.info strong', state_element).text(info_text || get_default_info_text());

						$('.info .details', state_element).hide();
					};

					var show_full_info = function show_full_info(info_text, elapsed_seconds) {
						show_info(info_text, elapsed_seconds);

						dataimport_compute_details(response, $('.info .details', state_element), elapsed_seconds || get_time_taken());
					};

					state_element.removeAttr('class');

					var current_time = new Date();
					$('.last_update abbr', state_element).text(current_time.toTimeString().split(' ').shift()).attr('title', current_time.toUTCString());

					$('.info', state_element).removeClass('loader');

					if ('busy' === status) {
						state_element.addClass('indexing');

						if (autorefresh_status) {
							$('.info', state_element).addClass('loader');
						}

						var time_elapsed_text = response.statusMessages['Time Elapsed'];
						var elapsed_seconds = app.convert_duration_to_seconds(time_elapsed_text);
						time_elapsed_text = app.convert_seconds_to_readable_time(elapsed_seconds);

						var info_text = time_elapsed_text ? 'Indexing since ' + time_elapsed_text : 'Indexing ...';

						show_full_info(info_text, elapsed_seconds);
					} else if (rollback_time) {
						state_element.addClass('failure');

						show_full_info();
					} else if (abort_time) {
						state_element.addClass('aborted');

						show_full_info('Aborting current Import ...');
					} else if ('idle' === status && 0 !== messages_count) {
						state_element.addClass('success');

						show_full_info();
					} else {
						state_element.addClass('idle');

						show_info('No information available (idle)');
					}

					// show raw status

					var code = $('<pre class="syntax language-json"><code>' + app.format_json(xhr.responseText).esc() + '</code></pre>');

					$('#raw_output_container', content_element).html(code);
					hljs.highlightBlock(code.get(0));

					if (!app.timeout && autorefresh_status) {
						app.timeout = window.setTimeout(function() {
							dataimport_fetch_status(true)
						}, dataimport_timeout);
					}
				},
				error : function(xhr, text_status, error_thrown) {
					console.debug(arguments);

					reload_config_element.addClass('error');
				},
				complete : function(xhr, text_status) {
					$('span', status_button).removeClass('loader').addClass('success');

					window.setTimeout(function() {
						$('span', status_button).removeClass('success');
					}, dataimport_timeout / 2);
				}
			});
		}

		// form

		var form = $('form', form_element);

		form.ajaxForm({
			url : handler_url,
			data : {
				wt : 'json',
				indent : 'true'
			},
			dataType : 'json',
			type : 'POST',
			beforeSend : function(xhr, settings) {
				$('button[type="submit"] span', form_element).addClass('loader');

				error_element.empty().hide();
			},
			beforeSubmit : function(array, form, options) {
				var entity = $('#entity', form).val();
				if (entity.length) {
					array.push({
						name : 'entity',
						value : entity
					});
				}

				var start = parseInt($('#start', form).val(), 10);
				if (start) {
					array.push({
						name : 'start',
						value : start
					});
				}

				var rows = parseInt($('#rows', form).val(), 10);
				if (rows) {
					array.push({
						name : 'rows',
						value : rows
					});
				}

				$('input:checkbox', form).not(':checked').each(function(i, input) {
					array.push({
						name : input.name,
						value : 'false'
					});
				});

				var custom_parameters = $('#custom_parameters', form).val();
				if (custom_parameters.length) {
					var params = custom_parameters.split('&');
					for ( var i in params) {
						var tmp = params[i].split('=');
						array.push({
							name : tmp[0],
							value : tmp[1]
						});
					}
				}

				if (debug_mode) {
					array.push({
						name : 'dataConfig',
						value : $('#dataimport_config .editable textarea').val()
					});
				}
			},
			success : function(response, text_status, xhr) {},
			error : function(xhr, text_status, error_thrown) {
				var response = null;
				try {
					eval('response = ' + xhr.responseText + ';');
				} catch (e) {}

				error_element.text(response.error.msg || 'Unknown Error (Exception w/o Message)').show();
			},
			complete : function(xhr, text_status) {
				$('button[type="submit"] span', form_element).removeClass('loader');

				var debug = $('input[name="debug"]:checked', form);
				if (0 !== debug.size()) {
					var code = $('<pre class="syntax language-json"><code>' + app.format_json(xhr.responseText).esc() + '</code></pre>');

					$('.content', debug_response_element).html(code);
					hljs.highlightBlock(code.get(0));
				}

				dataimport_fetch_status();
			}
		});

		$('input[name="debug"]', form).off('change').on('change', function(event) {
			debug_response_element.toggle(this.checked);
		});

		$('#auto-refresh-status a', form_element).off('click').on('click', function(event) {
			$.cookie(cookie_dataimport_autorefresh, $.cookie(cookie_dataimport_autorefresh) ? null : true);
			$(this).trigger('state');

			dataimport_fetch_status();

			return false;
		}).off('state').on('state', function(event) {
			autorefresh_status = !!$.cookie(cookie_dataimport_autorefresh);

			$.cookie(cookie_dataimport_autorefresh) ? $(this).addClass('on') : $(this).removeClass('on');
		}).trigger('state');
	});
});
